package main

import (
	"database/sql"
	"log"
	"real-time-communication/utils"
)

type Friend struct {
	Id        int    `json:"id" db:"id"`
	Applier   int    `json:"applier" db:"applier"`
	Receiver  int    `json:"receiver" db:"receiver"`
	Status    string `json:"status" db:"status"`
	ApplyTime string `json:"applyTime" db:"apply_time"`
}

type FriendListVo struct {
	UserId   int    `json:"userId" db:"user_id"`
	Nickname string `json:"nickname" db:"nickname"`
	Avatar   string `json:"avatar" db:"avatar"`
}

type FriendApplyListVo struct {
	Id        int    `json:"id" db:"id"`
	Applier   int    `json:"applier" db:"applier"`
	Receiver  int    `json:"receiver" db:"receiver"`
	Status    string `json:"status" db:"status"`
	UserId    int    `json:"userId" db:"user_id"`
	Nickname  string `json:"nickname" db:"nickname"`
	Avatar    string `json:"avatar" db:"avatar"`
	ApplyTime string `json:"applyTime" db:"apply_time"`
}

type SearchFriendVo struct {
	Id        sql.NullInt32  `json:"id" db:"id"`
	Applier   sql.NullInt32  `json:"applier" db:"applier"`
	Receiver  sql.NullInt32  `json:"receiver" db:"receiver"`
	Status    sql.NullString `json:"status" db:"status"`
	UserId    int            `json:"userId" db:"user_id"`
	Nickname  string         `json:"nickname" db:"nickname"`
	Avatar    string         `json:"avatar" db:"avatar"`
	ApplyTime sql.NullString `json:"applyTime" db:"apply_time"`
}

type DeleteFriendVo struct {
	UserId   int `json:"userId"`
	TargetId int `json:"targetId"`
}

// GetFriendList 获取好友列表
func GetFriendList(userId int, searchContent string) []FriendListVo {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return nil
	}
	defer db.Close()

	var friendList []FriendListVo

	if utils.IsEmpty(searchContent) {
		stmt, err := db.Prepare("SELECT u.user_id, u.nickname, u.avatar FROM friend AS f INNER JOIN user AS u ON (u.user_id = f.applier OR u.user_id = f.receiver) WHERE u.user_id != ? AND f.status = '1' AND (applier = ? OR receiver = ?)")
		if err != nil {
			log.Println("数据库异常", err)
			return nil
		}
		defer stmt.Close()

		rows, err := stmt.Query(userId, userId, userId)
		if err != nil {
			log.Fatal("数据库异常", err)
			return nil
		}

		for rows.Next() {
			var friend FriendListVo
			err := rows.Scan(&friend.UserId, &friend.Nickname, &friend.Avatar)
			if err != nil {
				log.Fatal("数据库异常", err)
				return nil
			}
			friendList = append(friendList, friend)
		}
		defer rows.Close()
	} else {
		stmt, err := db.Prepare("SELECT u.user_id, u.nickname, u.avatar FROM friend AS f INNER JOIN user AS u ON (u.user_id = f.applier OR u.user_id = f.receiver) WHERE u.user_id != ? AND f.status = '1' AND (applier = ? OR receiver = ?) AND u.nickname LIKE ?")
		if err != nil {
			log.Println("数据库异常", err)
			return nil
		}
		defer stmt.Close()

		rows, err := stmt.Query(userId, userId, userId, "%"+searchContent+"%")
		if err != nil {
			log.Fatal("数据库异常", err)
			return nil
		}

		for rows.Next() {
			var friend FriendListVo
			err := rows.Scan(&friend.UserId, &friend.Nickname, &friend.Avatar)
			if err != nil {
				log.Fatal("数据库异常", err)
				return nil
			}
			friendList = append(friendList, friend)
		}
		defer rows.Close()
	}

	return friendList
}

// GetFriendApplyList 获取好友申请列表
func GetFriendApplyList(userId int) []FriendApplyListVo {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return nil
	}
	defer db.Close()

	var friendList []FriendApplyListVo

	stmt, err := db.Prepare("SELECT f.id, f.applier, f.receiver, f.status, u.user_id, u.nickname, u.avatar, f.apply_time FROM friend AS f INNER JOIN user AS u ON (u.user_id = f.applier OR u.user_id = f.receiver) WHERE u.user_id != ? AND (applier = ? OR receiver = ?)")
	if err != nil {
		log.Println("数据库异常", err)
		return nil
	}
	defer stmt.Close()

	rows, err := stmt.Query(userId, userId, userId)
	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}

	for rows.Next() {
		var friend FriendApplyListVo
		err := rows.Scan(&friend.Id, &friend.Applier, &friend.Receiver, &friend.Status, &friend.UserId, &friend.Nickname, &friend.Avatar, &friend.ApplyTime)
		if err != nil {
			log.Fatal("数据库异常", err)
			return nil
		}
		friendList = append(friendList, friend)
	}
	defer rows.Close()

	return friendList
}

// SearchFriend 通过帐号搜索用户并获取好友关系
func SearchFriend(account string, userId int) *SearchFriendVo {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return nil
	}
	defer db.Close()

	var res SearchFriendVo
	stmt, err := db.Prepare("SELECT u.user_id, u.nickname, u.avatar, f.id, f.applier, f.receiver, f.status, f.apply_time FROM user AS u LEFT JOIN friend AS f ON ((u.user_id = f.applier AND f.receiver = ?) OR (u.user_id = f.receiver AND f.applier = ?)) WHERE u.username = ?")
	if err != nil {
		log.Fatal("数据库异常", err)
		return nil
	}
	defer stmt.Close()

	row := stmt.QueryRow(userId, userId, account)

	err = row.Scan(&res.UserId, &res.Nickname, &res.Avatar, &res.Id, &res.Applier, &res.Receiver, &res.Status, &res.ApplyTime)
	if err == sql.ErrNoRows {
		return nil
	} else if err != nil && err != sql.ErrNoRows {
		if err != nil {
			log.Fatal("数据库异常", err)
			return nil
		}
	}

	return &res
}

// ApplyFriend 新增好友关系，默认是待通过
func ApplyFriend(applier, receiver int) bool {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return false
	}
	defer db.Close()

	// 这里先删除前面所有被忽略的关系，以防报错
	stmt, err := db.Prepare("DELETE FROM friend WHERE (applier = ? AND receiver = ?) OR (applier = ? AND receiver = ?)")
	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}
	defer stmt.Close()

	_, err = stmt.Exec(applier, receiver, receiver, applier)
	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}

	stmt, err = db.Prepare("INSERT INTO friend (applier, receiver, apply_time) VALUES (?, ?,  DATETIME('now'))")
	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}

	_, err = stmt.Exec(applier, receiver)

	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}
	return true
}

// UpdateFriendStatus 修改好友之间的状态(待通过、通过、忽略)
func UpdateFriendStatus(applier, receiver int, status string) bool {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return false
	}
	defer db.Close()

	stmt, err := db.Prepare("UPDATE friend SET status = ? WHERE applier = ? AND receiver = ?")
	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}
	defer stmt.Close()

	_, err = stmt.Exec(status, applier, receiver)

	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}
	return true
}

func CheckIsFriend(userId, targetId int) bool {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return false
	}
	defer db.Close()

	var res int

	querySql := "SELECT COUNT(*) FROM friend WHERE (applier = ? AND receiver = ?) OR (applier = ? AND receiver = ?)"
	stmt, err := db.Prepare(querySql)
	if err != nil {
		log.Fatal("数据库异常:", err)
		return false
	}
	defer stmt.Close()

	row := stmt.QueryRow(userId, targetId, targetId, userId).Scan(&res)
	if row != nil {
		log.Println("数据库异常：", row.Error())
		return false
	}

	if res > 0 {
		return true
	}

	return false
}

func DeleteFriend(deleteFriendVo DeleteFriendVo) bool {
	db, err := sql.Open("sqlite3", "./RealTimeCommunication.db")
	if err != nil {
		log.Fatal("数据库打开失败:", err)
		return false
	}
	defer db.Close()

	stmt, err := db.Prepare("DELETE FROM friend WHERE (applier = ? AND receiver = ?) OR (applier = ? AND receiver = ?)")
	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}
	defer stmt.Close()

	_, err = stmt.Exec(deleteFriendVo.UserId, deleteFriendVo.TargetId, deleteFriendVo.TargetId, deleteFriendVo.UserId)

	if err != nil {
		log.Fatal("数据库异常", err)
		return false
	}
	return true
}
